﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MetadataBasedConfigArch.Framework.Model;

namespace MetadataBasedConfigArch.ProcessEngine
{
    public class ConfigMetadata : MetadataBasedConfigArch.Framework.IConfigMetadata
    {
        #region Ctor

        public ConfigMetadata()
        { 
        }

        public ConfigMetadata(Framework.IMetadataBasedEntityProvider entityProvider)
            :this()
        {
            EntityProvider = entityProvider;
        }

        #endregion

        #region  Properties

        public Framework.IMetadataBasedEntityProvider EntityProvider
        {
            get;
            protected set;
        }

        #endregion

        #region Implements Framework.IConfigMetadata interface

        public IConfigMeta ConfigMeta
        {
            get;
            protected set;
        }

        public ITenant Tenant
        {
            get;
            protected set;
        }

        protected List<IConfigMetaConfigData> _ConfigMetaConfigDatas;
        public List<IConfigMetaConfigData> ConfigMetaConfigDatas
        {
            get
            {
                if (_ConfigMetaConfigDatas == null)
                {
                    _ConfigMetaConfigDatas = LoadConfigDatas(Tenant.ID, ConfigMeta.ID);
                }
                return _ConfigMetaConfigDatas;
            }
        }

        public virtual void Load(ITenant tenant, IConfigMeta configMeta, bool loadData)
        {
            Tenant = tenant;
            ConfigMeta = configMeta;
            
            if (loadData)
            {
                _ConfigMetaConfigDatas = LoadConfigDatas(tenant.ID, configMeta.ID);
            }
        }

        public virtual void Load(ITenant tenant, Int64 configMetaID, bool loadData)
        {
            IConfigMeta configMeta = EntityProvider.Load<IConfigMeta>(c=>c.ID==configMetaID).FirstOrDefault();
            Load(tenant, configMeta, loadData);
        }

        public virtual void Load(Int64 tenantID, IConfigMeta configMeta, bool loadData)
        {
            ITenant tenant = EntityProvider.Load<ITenant>(t=>t.ID == tenantID).FirstOrDefault();
            Load(tenant, configMeta, loadData);
        }

        public virtual void Load(Int64 tenantID, Int64 configMetaID, bool loadData)
        {
            IConfigMeta configMeta = EntityProvider.Load<IConfigMeta>(c => c.ID == configMetaID).FirstOrDefault();
            ITenant tenant = EntityProvider.Load<ITenant>(t => t.ID == tenantID).FirstOrDefault();
            Load(tenant, configMeta, loadData);
        }

        #endregion

        #region Virtual Protected Methods

        protected virtual List<IConfigMetaConfigData> LoadConfigDatas(Int64 tenantID, Int64 configMetaID)
        {
            // Using Linq
            //return EntityProvider.Load<Model.ConfigMetaConfigData>(dlist =>
            //        {
            //            if (dlist is System.Data.Objects.ObjectQuery<Model.ConfigMetaConfigData>)
            //            {
            //                var objectQueryList = dlist as System.Data.Objects.ObjectQuery<Model.ConfigMetaConfigData>;
            //                return (from cd in objectQueryList.Include("ConfigMetaConfigInfo")
            //                        where cd.TenantID == tenantID
            //                          && cd.ConfigMetaConfigInfo.TenantID == tenantID
            //                          && cd.ConfigMetaConfigInfo.ConfigMeta == configMetaID
            //                        select cd);
            //            }
            //            else  // Not Use Data Entity
            //            {
            //                return new List<Model.ConfigMetaConfigData>();
            //            }
            //        })
            //        .ToList()
            //        .Select(mcd => (Framework.IConfigMetaConfigData)(mcd))
            //        .ToList();

            //Using Store Precedure
            return EntityProvider.GetConfigMetaConfigDatas(tenantID, configMetaID).ToList();
        }

        protected virtual void OnInitializing(Framework.IMetadataBasedEntityProvider entityProvider)
        {           
        }

        #endregion

        #region Initialize Methods

        public void Initialize(Framework.IMetadataBasedEntityProvider entityProvider)
        {
            OnInitializing(entityProvider);
            EntityProvider = entityProvider;
        }

        #endregion
    }
}
